import 'package:casdon/common/service/tuya_service.dart';
import 'package:casdon/core/logger/log.dart';
import 'package:casdon/modules/recipe/data/api/miffy_product_list_api.dart';
import 'package:casdon/modules/recipe/data/model/miffy_recipe_cloud_model.dart';

import 'package:casdon/modules/recipe/data/model/recipe_cloud_model.dart';
import 'package:casdon/modules/recipe/domain/states/recipe_cloud_list_state.dart';
import 'package:casdon/modules/recipe/domain/usecase/miffy_product_list_usecase.dart';
import 'package:casdon/modules/recipe/domain/usecase/miffy_recipe_cloud_list_usecase.dart';
import 'package:casdon/modules/recipe/domain/usecase/recipe_cloud_list_usecase.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:tuya_home_sdk_flutter/tuya_home_sdk_flutter.dart';

class RecipeCloudListNotifier extends AsyncNotifier<RecipeCloudListState> {
  bool _isRefreshing = false;

  @override
  Future<RecipeCloudListState> build() async {
    final previous = state.valueOrNull ?? RecipeCloudListState.initial();
    try {
      final miffyState = await _fetchMiffyAllData();
      final ciotstate = await _fetchAllData();
      return ciotstate.merge(miffyState);
    } catch (e, st) {
      Log.e("初始化智能云菜谱失败", e, st);
      return previous;
    }
  }

  Future<void> refresh() async {
    if (_isRefreshing) return;
    _isRefreshing = true;
    final previous = state.valueOrNull ?? RecipeCloudListState.initial();

    try {
      final miffyState = await _fetchMiffyAllData();
      final ciotstate = await _fetchAllData();

      RecipeCloudListState mergedState = ciotstate.merge(miffyState);

      state = AsyncData(mergedState);
    } catch (e, st) {
      state = AsyncData(previous);
      Log.e("加载智能云菜谱失败", e, st);
    } finally {
      _isRefreshing = false;
    }
  }

  Future<void> loadMore() async {
    await loadCiotMore();
    await loadMiffyMore();
  }

  Future<void> loadCiotMore() async {
    final snapshot = state.valueOrNull ?? RecipeCloudListState.initial();
    final newState = snapshot.copyWith();
    int currentIndex = newState.selectedIndex;
    if (currentIndex < 0 || currentIndex >= newState.devList.length) {
      return;
    }
    var devModel = newState.devList[currentIndex];
    if (isMiffyProduct(pid: devModel.productId)) {
      return;
    }
    final devCloud = newState.getDeviceRecipeCloud(devModel.devId!);
    if (devCloud.totalSize <= devCloud.data.length && devCloud.totalSize != 0) {
      return;
    }
    final usecase = ref.read(recipeCloudListUsecaseProvider);

    try {
      final response = await usecase.execute(
        pid: devModel.productId,
        pageNum: devCloud.pageNum + 1,
        pageSize: newState.pageSize,
      );

      if (response.rows == null || response.rows!.isEmpty) {
        state = AsyncData(newState);
        return;
      }

      final recipeCloudList = RecipeCloudModel.listFromApi(response.rows ?? []);
      final updatedDevCloud = devCloud.copyWith(
        data: [...devCloud.data, ...recipeCloudList],
        pageNum: devCloud.pageNum + 1,
        totalSize: response.total,
        deviceId: devModel.devId!,
        pid: devModel.productId,
      );

      state = AsyncData(newState.updateDeviceRecipeCloud(updatedDevCloud));
    } catch (e, st) {
      state = AsyncData(snapshot);
      Log.e("加载CIOT云菜谱更多失败", e, st);
    }
  }

  Future<void> loadMiffyMore() async {
    final snapshot = state.valueOrNull ?? RecipeCloudListState.initial();
    final newState = snapshot.copyWith();
    int currentIndex = newState.selectedIndex;
    if (currentIndex < 0 || currentIndex >= newState.devList.length) {
      return;
    }
    var devModel = newState.devList[currentIndex];
    if (isMiffyProduct(pid: devModel.productId) == false) {
      return;
    }

    final devCloud = newState.getDeviceRecipeCloud(devModel.devId!);
    if (devCloud.totalSize <= devCloud.data.length && devCloud.totalSize != 0) {
      return;
    }
    final usecase = ref.read(miffyRecipeCloudListUsecaseProvider);

    try {
      final response = await usecase.execute(
        pid: devModel.productId,
        pageNum: devCloud.pageNum + 1,
        pageSize: newState.pageSize,
      );

      if (response.recipeMenuVoList == null ||
          response.recipeMenuVoList!.isEmpty) {
        state = AsyncData(newState);
        return;
      }
      final recipeCloudList = MiffyRecipeCloudModel.listFromApi(
        response.recipeMenuVoList ?? [],
      );

      final updatedDevCloud = devCloud.copyWith(
        data: [...devCloud.data, ...recipeCloudList],
        pageNum: devCloud.pageNum + 1,
        totalSize: response.total,
        deviceId: devModel.devId!,
        pid: devModel.productId,
      );

      state = AsyncData(newState.updateDeviceRecipeCloud(updatedDevCloud));
    } catch (e, st) {
      state = AsyncData(snapshot);
      Log.e("加载Miffy云菜谱更多失败", e, st);
    }
  }

  // 新ciot设备获取云菜谱数据
  Future<RecipeCloudListState> _fetchAllData() async {
    final currentState = state.valueOrNull ?? RecipeCloudListState.initial();
    final newState = currentState.copyWith();

    final usecase = ref.read(recipeCloudListUsecaseProvider);

    try {
      final list = await TuyaService().homeDeviceList();
      if (list.isEmpty) {
        return newState.copyWith(data: [], devList: [], selectedIndex: 0);
      }

      // 准备新的设备菜谱列表
      final updatedDeviceClouds = <DeviceRecipeCloud>[];
      final updatedDeviceList = <ThingSmartDeviceModel>[];
      final updatedDeviceIsMiffy = <bool>[];
      for (final devModel in list) {
        if (devModel.devId == null) continue;
        if (isMiffyProduct(pid: devModel.productId)) continue;

        final devCloud = newState.getDeviceRecipeCloud(devModel.devId!);

        final response = await usecase.execute(
          pid: devModel.productId,
          pageNum: 1,
          pageSize: newState.pageSize,
        );

        if (response.total <= 0 ||
            response.rows == null ||
            response.rows!.isEmpty) {
          continue;
        }
        updatedDeviceList.add(devModel);
        updatedDeviceIsMiffy.add(false);
        final recipeCloudList = RecipeCloudModel.listFromApi(
          response.rows ?? [],
        );

        updatedDeviceClouds.add(
          devCloud.copyWith(
            data: recipeCloudList,
            totalSize: response.total,
            deviceId: devModel.devId!,
            pid: devModel.productId,
            pageNum: 1,
          ),
        );
      }
      int selectedIndex = newState.selectedIndex;
      if (selectedIndex >= updatedDeviceClouds.length &&
          updatedDeviceClouds.isNotEmpty) {
        selectedIndex = 0;
      }
      return newState.copyWith(
        data: updatedDeviceClouds,
        devList: updatedDeviceList,
        selectedIndex: selectedIndex,
        isMiffyList: updatedDeviceIsMiffy,
      );
    } catch (e, st) {
      Log.e("获取CIOT云菜谱失败", e, st);
      return currentState;
    }
  }

  // miffy设备获取云菜谱数据
  Future<RecipeCloudListState> _fetchMiffyAllData() async {
    RecipeCloudListState? currentState;
    if (state.valueOrNull != null) {
      currentState = state.value;
    } else {
      currentState = RecipeCloudListState.initial();
    }

    RecipeCloudListState newState = currentState!.copyWith();
    final usecase = ref.read(miffyRecipeCloudListUsecaseProvider);

    try {
      final list = await TuyaService().homeDeviceList();
      if (list.isEmpty) {
        return newState.copyWith(data: [], devList: [], selectedIndex: 0);
      }

      final updatedDeviceClouds = <DeviceRecipeCloud>[];

      final updatedDeviceList = <ThingSmartDeviceModel>[];

      final updatedDeviceIsMiffy = <bool>[];

      for (final devModel in list) {
        if (devModel.devId == null) continue;
        if (isMiffyProduct(pid: devModel.productId) == false) continue;

        final devCloud = newState.getDeviceRecipeCloud(devModel.devId!);

        final response = await usecase.execute(
          pid: devModel.productId,
          pageNum: 1,
          pageSize: newState.pageSize,
        );

        if (response.total <= 0 ||
            response.recipeMenuVoList == null ||
            response.recipeMenuVoList!.isEmpty) {
          continue;
        }
        updatedDeviceList.add(devModel);
        updatedDeviceIsMiffy.add(true);
        final recipeCloudList = MiffyRecipeCloudModel.listFromApi(
          response.recipeMenuVoList ?? [],
        );

        updatedDeviceClouds.add(
          devCloud.copyWith(
            data: recipeCloudList,
            totalSize: response.total,
            deviceId: devModel.devId!,
            pid: devModel.productId,
            pageNum: 1,
          ),
        );
      }
      int selectedIndex = newState.selectedIndex;
      if (selectedIndex >= updatedDeviceClouds.length &&
          updatedDeviceClouds.isNotEmpty) {
        selectedIndex = 0;
      }
      return newState.copyWith(
        data: updatedDeviceClouds,
        devList: updatedDeviceList,
        isMiffyList: updatedDeviceIsMiffy,
        selectedIndex: selectedIndex,
      );
    } catch (e, st) {
      Log.e("获取Miffy云菜谱失败", e, st);
      return currentState!;
    }
  }

  void selectDevice(int index) {
    final currentState = state.valueOrNull ?? RecipeCloudListState.initial();
    RecipeCloudListState newState = currentState.copyWith();
    if (index < 0 || index > newState.devList.length) {
      return;
    }

    newState.selectedIndex = index;
    state = AsyncValue.data(newState);
  }

  ThingSmartDeviceModel? selectedDevice() {
    if (state.value == null) return null;

    int index = state.value!.selectedIndex;
    if (index < 0 || index > state.value!.devList.length) {
      return null;
    }
    return state.value!.devList[index];
  }

  bool isMiffyProduct({required String pid}) {
    final List<MiffyProduct>? miffyProducts = ref
        .read(miffyRecipeProductListProvider)
        .valueOrNull;

    if (miffyProducts == null) {
      return false;
    }
    try {
      return miffyProducts.firstWhere((p) => p.tuyaPid == pid) == null
          ? false
          : true;
    } catch (_) {
      return false; // 现在合法
    }
  }
}

final recipeCloudListNotifierProvider =
    AsyncNotifierProvider<RecipeCloudListNotifier, RecipeCloudListState>(
      () => RecipeCloudListNotifier(),
    );
